// ==================================================================================
// Shared Genomics Project MPI Codebase
// Version 1.0 30/04/2010
//
// (c) 2010 University of Manchester all rights reserved
//
// This file is distributed under the GNU General Public License, Version 2.  
// Please see the file COPYING.txt for more details
// ==================================================================================

#ifndef _BMAPFILE_H_
#define _BMAPFILE_H_

#include "mapfile.h"
#include "chromosomes.h"
#include "options.h"
#include "types.h"

#ifdef __cplusplus
extern "C" {
#endif

/*!
\file
\ingroup	gio
\brief		SNP List for MPI Cores
\details 
	This header file defines methods to manipulate a list of SNPs.<br>
	The SNP data structure was derived from a PLINK representation but uses fewer variables 
	so is to referred to as the 'small' locus in this documentation.<br>
	The SNP list is referred as a BMAP file and uses the file suffix \ref SUFFIX_BMAP_FILE.
*/

/*! \brief Maximum length of an NCBI SNP identifier. */
#define SMALL_LOCUS_NAME_LENGTH 12

/*! \brief Maximum length of characters representing allelic data (e.g. 0, 1 or 2). */
#define ALLELE_LENGTH 2

/*!
\brief SNP Identifier (MPI)
\details
	This struct is a more compact version of the \ref locus.<br>
	The \ref locus was taken directly from the PLINK codebase but as NIBHI needed
	only a sub-set of algorithms implemented by PLINK, a lot of the superfluous
	fields were removed which in turn created the definition for the \ref small_locus structure .
*/
struct small_locus {
	/*! \brief Unique SNP Identifier (typically NCBI RS number) */
	char name[SMALL_LOCUS_NAME_LENGTH];

	/*! \brief Base-pair position */
	int bp;

	/*! \brief Chromosomal number */
	short chr;

	/*! 
	\brief Logical flag
	\deprecated Not used by current set of algorithms.
	*/
	BOOL A;

	/*! 
	\brief Logical flag
	\deprecated Not used by current set of algorithms.
	*/
	BOOL B;

	/*! 
	\brief Character code of first allelic data read from input file.
	\deprecated Not used any calculation code, may be superfluous.
	*/
	char allele1[ALLELE_LENGTH]; 

	/*! 
	\brief Character code of second allelic data read from input file. 
	\deprecated Not used any calculation code, may be superfluous.
	*/
	char allele2[ALLELE_LENGTH];
};

/*! 
\brief Create a bmap file (i.e. a SNP list for the NIBHI cluster).
\details
	A BMAP file is an array of \ref small_locus written to file.<br>
	It is a compacted data format used to transfer a list of SNPs onto the cores of
	the NIBHI cluster.<br>
	The source data for the BMAP is located in a \ref mapfile structure.<br>
	The \ref mapfile is populated with information from PLINK-compatible text inputs.<br>
	The output file name is bound to the variable \ref selected_options::szBmapFileName.<br>
	Typically output file uses the suffix \ref SUFFIX_BMAP_FILE.
\param [in] m Source list of SNPs, full genomic data-set.
\param [in] c Human chromosomal model
\param [in] ops Location of the output file (\ref selected_options::szBmapFileName)
\returns 1 on success, 0 on failure
*/
int bmapfile_create(struct mapfile *m, struct chromosomes *c, struct selected_options *ops);

/*! 
\brief Load a SNP list from file. 
\details
	Function loads a SNP list from a BMAP file.<br>
	The input file name is bound to the variable \ref selected_options::szBmapFileName.<br>
	Typically output file uses the suffix \ref SUFFIX_BMAP_FILE.
\param [in] ops Location of the input file (\ref selected_options::szBmapFileName)
\param [in,out] nSnps pointer where number of SNPs in BMAP written to.
\returns array of \ref small_locus or NULL on failure.
*/
struct small_locus* bmapfile_load(struct selected_options *ops, int *nSnps);

/*!
\brief Read the number of SNPs in a BMAP file 
\details
	Rarely used convenience method used to get list size so can program can allocate
	memory.<br>
	The input file name is bound to the variable \ref selected_options::szBmapFileName.<br>
\param [in]  ops Input file location
\returns No. SNPs in BMAP file or zero on failure.
\deprecated Method only used by a single program and no unit tests so may be able to eliminate from the codebase.
*/
int bmapfile_read_nSNPs(struct selected_options *ops);

/*!
\brief Load a sub-set of SNPs from a larger list.
\details
	The input file of SNPs is bound to the variable \ref selected_options::szBmapFileName.
\param [in] ops Input file location
\param [in] start SNP index to read from.
\param [in] end SNP index to read up to.
\returns array of \ref small_locus or NULL on failure.
*/
struct small_locus* bmapfile_fseek(struct selected_options *ops, int start, int end);

/*!
\brief Write a filtered SNP list to file.
\details
	A list of SNPs are written to an output BMAP file only if they are not
	flagged to be deleted from the data-set.<br>
	The 'snps_to_del' array is populated with data by the filtering code (see \ref bfilter.h).<br>
	An output file is created locally and then copied to a remote working directory.<br>
	The output file name is a concatonation of the remote working directory, 
	\ref selected_options::szRunId and \ref SUFFIX_BMAP_FILE .
\param [in] m Full list of SNPs in data-set
\param [in] nSNPs No. SNPs in the data-set
\param [in] snps_to_del Array of SNPs to remove from the data-set
\param [in] ops Output file location
\param [in] ldir Local working directory
\param [in] rdir Remote working directory
*/
int bmapfile_write_filtered(struct small_locus *m, int nSNPs, BOOL *snps_to_del, struct selected_options *ops, char *ldir, char *rdir);

/*!
\brief Create a BMAP file and copy to a remore directory.
\details
	Create a BMAP file from a populated SNP-major genomic data-set (see \ref mapfile)
	and copies the output file to a remote directory.<br>
	The output file path is a concatonation of \ref selected_options::rdir, 
	\ref selected_options::szRunId and \ref SUFFIX_BMAP_FILE .
\param[in] m SNP-major genomic data-set
\param[in] c Chromosomal model
\param[in] ops Output file location
\param[in] rank Rank of the local processor
\returns 1 on success or 0 on failure
*/
int bmapfile_create_and_copy(struct mapfile *m, struct chromosomes *c, struct selected_options *ops, int rank);

/*! 
\brief Load a BMAP file
\details
	The input file path is a concatonation of \ref selected_options::rdir, 
	\ref selected_options::szRunId and \ref SUFFIX_BMAP_FILE .
\param [in] ops Input file location
\param [in, out] nSnps size of the loaded array
\return an array of \ref small_locus or NULL on failure
*/
struct small_locus* _bmapfile_load(struct selected_options *ops, int *nSnps);

#ifdef __cplusplus
}
#endif

#endif // _BMAPFILE_H_
